#!/bin/bash

set -e

user="oracle"
manual_size=""
output_file="/etc/sysctl.d/oracle.conf"

# Help message
usage() {
    echo "Usage: $0 [-u oracle_user] [-s size]"
    echo "  -u  Specify Oracle user, default is 'oracle'"
    echo "  -s  Manually specify total shared memory size, supports G/M/K units (e.g. 8G, 1024M)"
    exit 1
}

# Unit conversion function (convert to bytes)
parse_size() {
    local input="$1"
    if [[ "$input" =~ ^[0-9]+[Gg]$ ]]; then
        echo $(( ${input%[Gg]} * 1024 * 1024 * 1024 ))
    elif [[ "$input" =~ ^[0-9]+[Mm]$ ]]; then
        echo $(( ${input%[Mm]} * 1024 * 1024 ))
    elif [[ "$input" =~ ^[0-9]+[Kk]$ ]]; then
        echo $(( ${input%[Kk]} * 1024 ))
    elif [[ "$input" =~ ^[0-9]+$ ]]; then
        echo $(( input * 1024 * 1024 ))  # Default to MB
    else
        echo "Invalid size format: $input"
        exit 1
    fi
}

# Parse arguments
while getopts ":u:s:h" opt; do
    case ${opt} in
        u)
            user="$OPTARG"
            ;;
        s)
            manual_size="$OPTARG"
            ;;
        h|*)
            usage
            ;;
    esac
done

# Get HugePage size in bytes
hugepagesize_kb=$(grep Hugepagesize /proc/meminfo | awk '{print $2}')
hugepagesize_bytes=$(( hugepagesize_kb * 1024 ))

# Calculate total shared memory size
if [[ -n "$manual_size" ]]; then
    total_shm=$(parse_size "$manual_size")
else
    total_shm=$(ipcs -m | awk -v user="$user" '$3 == user {sum += $5} END {print sum}')
    if [[ -z "$total_shm" || "$total_shm" -eq 0 ]]; then
        echo "No shared memory segments found for user $user. Please check the username or shared memory status."
        exit 1
    fi
fi

# Calculate required number of HugePages (+5 as buffer)
nr_hugepages=$(( (total_shm + hugepagesize_bytes - 1) / hugepagesize_bytes + 5 ))

# Get current system setting
current_hugepages=$(sysctl -n vm.nr_hugepages)

# Compare and notify
if [[ "$current_hugepages" -ne "$nr_hugepages" ]]; then
    echo "Current system setting: vm.nr_hugepages = $current_hugepages"
    echo "Calculated required setting: vm.nr_hugepages = $nr_hugepages"
    echo "NOTE: The current setting does not match the required value."
else
    echo "Current system HugePages setting matches the calculated value: $nr_hugepages"
fi

# Output the config line
echo "vm.nr_hugepages = $nr_hugepages"
